/* Hello World Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "user_iic.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "portmacro.h"
#include "event_groups.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_err.h"
#include "esp_event.h"
#include "esp_wifi.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "driver/adc.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "autolink.h"
#include "button.h"
#include "oled.h"
#include "sht31.h"
#include "bmp280.h"
#include "ws2812.h"


//设备信息
#define BUTTON_GPIO 2
#define BUF_SIZE (1024)
//近场发现自定义消息
uint8_t deviceInfo[100] = {};

int flagNet = 0;

static char deviceUUID[17];

xQueueHandle SHT31ToOLEDQueueHandler = NULL;
xQueueHandle SHT31ToMqttQueueHandler = NULL;

xQueueHandle BMP280ToOLEDQueueHandler = NULL;
xQueueHandle BMP280ToMqttQueueHandler = NULL;

xQueueHandle S12SDToOLEDQueueHandler = NULL;
xQueueHandle S12SDToMqttQueueHandler = NULL;

//长按函数
static void ButtonLongPressCallBack(void *arg)
{
	xTaskCreate(TaskRestartSystem, "TaskRestartSystem", 1024, NULL, 6, NULL);
}

/**
 * @description: 按键驱动
 * @param {type}
 * @return:
 */
void TaskButton(void *pvParameters)
{
	//定义一个 gpio 下降沿触发: GPIO口，回调函数个数0开始，下降沿有效
	button_handle_t btn_handle = button_dev_init(BUTTON_GPIO, 1, BUTTON_ACTIVE_LOW);
	// 50ms按钮短按
	// BUTTON_PUSH_CB 表示按下就触发回调函数，如果设置了长按，这个依然会同时触发！
	// BUTTON_RELEASE_CB 表示释放才回调，如果设置了长按，这个依然会同时触发！
	// BUTTON_TAP_CB 此选项释放才回调，如果设置了长按，这个不会同时触发！
	// 设置长按 2s后触发
	button_dev_add_press_cb(0, ButtonLongPressCallBack, NULL, 2000 / portTICK_PERIOD_MS, btn_handle);

	vTaskDelete(NULL);
}


void S12SD_Task(void *pvParameters)
{
	uint16_t Data_P;
	adc_config_t adc_conf;
	adc_conf.clk_div = 8;
	adc_conf.mode = 0;

	adc_init(&adc_conf);

    if(S12SDToOLEDQueueHandler == NULL)
    	S12SDToOLEDQueueHandler = xQueueCreate(1, sizeof(float));
    if(S12SDToMqttQueueHandler == NULL)
    	S12SDToMqttQueueHandler = xQueueCreate(1, sizeof(float));

    while(1)
	{
    	adc_read(&Data_P);

    	float DataF_P = Data_P/1024.0*3.35*1000;
    	DataF_P = -0.7151 + 0.0086*DataF_P;
    	if(DataF_P < 0)
    		DataF_P = 0;
    	printf("UVindex = %3.2f\n", DataF_P);
		xQueueSend(S12SDToOLEDQueueHandler, (void *)&DataF_P, 10/portTICK_PERIOD_MS);
		xQueueSend(S12SDToMqttQueueHandler, (void *)&DataF_P, 10/portTICK_PERIOD_MS);
		vTaskDelay(1000/portTICK_PERIOD_MS);
	}

}

void BMP280_Task(void *pvParameters)
{
	long Data_P;

    BMP280_Init();

    if(BMP280ToOLEDQueueHandler == NULL)
    	BMP280ToOLEDQueueHandler = xQueueCreate(1, sizeof(long));
    if(BMP280ToMqttQueueHandler == NULL)
    	BMP280ToMqttQueueHandler = xQueueCreate(1, sizeof(long));

    while(1)
	{
    	Data_P = BMP280_GetValue();

    	printf("Pressure = %6ld\n", Data_P);
		xQueueSend(BMP280ToOLEDQueueHandler, (void *)&Data_P, 10/portTICK_PERIOD_MS);
		xQueueSend(BMP280ToMqttQueueHandler, (void *)&Data_P, 10/portTICK_PERIOD_MS);
		vTaskDelay(1000/portTICK_PERIOD_MS);
	}

}


void SHT31_Task(void *pvParameters)
{
    float data[2] = {0.0};
    float *data_send = data;

    SHT31_ModeSet();

    if(SHT31ToOLEDQueueHandler == NULL)
    	SHT31ToOLEDQueueHandler = xQueueCreate(1, sizeof(float *));
    if(SHT31ToMqttQueueHandler == NULL)
    	SHT31ToMqttQueueHandler = xQueueCreate(1, sizeof(float *));

    while(1)
	{
    	SHT31_ReadTempHum(data);

    	printf("temp = %2.2f \thum = %2.2f\n", data[0], data[1]);
		xQueueSend(SHT31ToOLEDQueueHandler, (void *)&data_send, 10/portTICK_PERIOD_MS);
		xQueueSend(SHT31ToMqttQueueHandler, (void *)&data_send, 10/portTICK_PERIOD_MS);

		vTaskDelay(1000/portTICK_PERIOD_MS);
	}

}

void Oled_Task(void *pvParameters)
{
	OLED_Init();
	OLED_CLS();
	OLED_ShowStr(28, 0, "Hello_World", 1);
	float* temp;
	long Pressure;
	float UVindex;
	BaseType_t err;
	char show[16];
	while(1)
	{
		if(SHT31ToOLEDQueueHandler != NULL)
		{

			err=xQueueReceive(SHT31ToOLEDQueueHandler, &temp, 100/portTICK_PERIOD_MS);
			if(err==pdTRUE)
			{
				sprintf(show ,"temp = %5.2fC", temp[0]);
				OLED_ShowStr(30, 2, show, 1);
				sprintf(show ," hum = %5.2f%%", temp[1]);
				OLED_ShowStr(30, 3, show, 1);
			}
		}
		if(S12SDToOLEDQueueHandler != NULL)
		{

			err=xQueueReceive(S12SDToOLEDQueueHandler, &UVindex, 100/portTICK_PERIOD_MS);
			if(err==pdTRUE)
			{
				sprintf(show ," UVindex = %5.2f", UVindex);
				OLED_ShowStr(6, 4, show, 1);
			}
		}
		if(BMP280ToOLEDQueueHandler != NULL)
		{
			err=xQueueReceive(BMP280ToOLEDQueueHandler, &Pressure, 100/portTICK_PERIOD_MS);
			if(err==pdTRUE)
			{
				sprintf(show ,"pressure = %5.2fKpa", Pressure/1000.0);
				OLED_ShowStr(6, 5, show, 1);
			}
		}
		vTaskDelay(100/portTICK_PERIOD_MS);
	}
}


void app_main()
{
	vTaskDelay(500 / portTICK_PERIOD_MS);
	//Initialize NVS
	esp_err_t ret = nvs_flash_init();
	if (ret == ESP_ERR_NVS_NO_FREE_PAGES)
	{
		ESP_ERROR_CHECK(nvs_flash_erase());
		ret = nvs_flash_init();
	}
	ESP_ERROR_CHECK(ret);

	printf("\n\n-------------------------------- Get Systrm Info------------------------------------------\n");
	//获取IDF版本
	printf("     SDK version:%s\n", esp_get_idf_version());
	//获取芯片可用内存
	printf("     esp_get_free_heap_size : %d  \n", esp_get_free_heap_size());
	//获取从未使用过的最小内存
	printf("     esp_get_minimum_free_heap_size : %d  \n", esp_get_minimum_free_heap_size());
	//获取芯片的内存分布，返回值具体见结构体 flash_size_map
	printf("     system_get_flash_size_map(): %d \n", system_get_flash_size_map());

	//获取mac地址（station模式）
	uint8_t mac[6];
	esp_read_mac(mac, ESP_MAC_WIFI_STA);
	sprintf(deviceUUID, "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
	sprintf((char *)deviceInfo, "{\"type\":\"%s\",\"mac\":\"%s\"}", "mqtt_app", deviceUUID);

    /* Print chip information */
    esp_chip_info_t chip_info;
    esp_chip_info(&chip_info);
    printf("This is ESP8266 chip with %d CPU cores, WiFi, ", chip_info.cores);

    printf("silicon revision %d, ", chip_info.revision);

    printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
            (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");

    SmartConfigInit();
    I2C_Configuration();
    WS2812_spi_mode_init();

    WS2812BSend_24bit(0xFF, 0x00, 0x00);

    taskENTER_CRITICAL();
    xTaskCreate(TaskButton,   "TaskButton", 1024, NULL, 6, NULL);
    xTaskCreate(Oled_Task,    "Oled_Task",  1024*2, NULL, 10, NULL);
    xTaskCreate(SHT31_Task,   "SHT31_Task", 1024*2, NULL, 10, NULL);
    xTaskCreate(BMP280_Task,  "BMP280_Task", 1024*2, NULL, 10, NULL);
    xTaskCreate(S12SD_Task,   "S12SD_Task", 1024*2, NULL, 10, NULL);
    taskEXIT_CRITICAL();

    vTaskDelete(NULL);

    while(1)
    	vTaskDelay(1000 / portTICK_PERIOD_MS);
}
